import { RouteManager } from './routeManager';
import { AuthenService } from '../../../service/authenService';
import * as Koa from 'koa';
import { AuthException, ServiceException } from '../../excpetion';
import { config, ServiceType } from '../../../config';
import { RemoteAuthenService } from '../../../service/remoteAuthenService';

export interface IRouteItem {
    target?: any;
    method: string;
    path: string;
    verify?: HttpVerify;
}

export function route(config: IRouteItem) {
    return (target: any, name: string, value: PropertyDescriptor) => {
        let c = RouteManager.Current.AddController(target.toString(), target);
        RouteManager.Current.AddRoute(
            {
                target: c,
                path: config.path,
                method: config.method,
                verify: config.verify
            },
            target[name]
        );
    }
}

export class RouteOptionsBase implements IRouteItem {
    constructor(method: string, path: string) {
        this.method = method;
        this.path = path;
    }
    target?: any;
    method: string;
    path: string;
    verify?: HttpVerify;
}

export class RouteOptionsVerify extends RouteOptionsBase {
    constructor(method: string, path: string, needVerifyStore: boolean = true, needVerifyToken: boolean = true) {
        super(method, path);
        this.verify = new HttpVerify(needVerifyStore, needVerifyToken);
    }
}

let authSvr;
if (config.type.indexOf(ServiceType.ModuleSYS) > -1 || config.type.indexOf(ServiceType.GrayscaleSYS) > -1) {
    authSvr = new RemoteAuthenService();
}
else {
    authSvr = new AuthenService();
}

export class HttpVerify {
    constructor(private needVerifyStore: boolean = true, private needVerifyToken: boolean = true) {
    }
    get NeedVerifyStore() {
        return this.needVerifyStore;
    }
    get NeedVerifyToken() {
        return this.needVerifyToken;
    }

    TokenVerify(token: string): Promise<void>;
    TokenVerify(ctx: Koa.Context, next): Promise<void>;
    async TokenVerify() {
        let token;
        if (arguments.length == 1) {
            token = arguments[0];
        }
        else if (arguments.length == 2) {
            let ctx = arguments[0];
            let next = arguments[1];
            token = ctx.headers['token'];
        }

        let t = await authSvr.GetToken(token);
        if (t === null) throw new AuthException();
    }

    StoreVerify(storeId: string): void;
    StoreVerify(ctx: Koa.Context, next): void;
    StoreVerify() {
        let storeId;
        if (arguments.length == 1) {
            storeId = arguments[0];
            if (!storeId) throw new ServiceException('没有传入店铺id！');
        }
        else if (arguments.length == 2) {
            let ctx = arguments[0];
            let next = arguments[1];
            storeId = ctx.headers['storeid'];
            if (!storeId) throw new ServiceException('没有传入店铺id！');
            if (ctx.request.body && !(ctx.request.body instanceof Array)) {
                ctx.request.body.storeId = storeId;
            }
        }
    }
} 